1️⃣ 生成并配置 SSH 密钥
在 Jenkins 服务器上生成密钥(如果尚未有可用的):
1
2# -c 内容是注释,可读即可
ssh-keygen -t ed25519 -C "jenkins@build"生成
~/.ssh/id_ed25519
和id_ed25519.pub
。将公钥添加到目标服务器:
1
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@target-server
测试是否免密登录, 这部分很重要,可以-vvv查看具体过程
1
2
3
4
5
6
7ssh user@target-server "echo OK"
# user必须是目标服务器用户名, 在.ssh目录下执行
ssh -vvv -i ~/.ssh/id_ed25519 \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
user@host在 Jenkins 中配置凭据
Jenkins → Manage Jenkins → Credentials → Global credentials
新建 SSH Username with private key
填:
- ID:
deploy-key
(供 Pipeline 使用) - Username:目标服务器用户名
- Private Key:直接粘贴
id_ed25519
内容或“从文件”读取
- ID:
2️⃣ Jenkinsfile 示例
使用 Declarative Pipeline 方式:
1 | pipeline { |
关键点说明
- sshagent:Pipeline 插件
SSH Agent
提供的步骤,会自动加载配置好的私钥。 StrictHostKeyChecking=no
:避免首次连接需人工确认指纹。--strip-components=1
:解压时去掉顶层目录。systemctl restart myapp.service
:根据实际服务名修改。
3️⃣ 服务器端准备
- 目标路径
/opt/apps/myapp
需存在并且user
有写权限。 - 如果用
systemd
管理应用,需要提前配置好myapp.service
。
4️⃣ 常见问题排查
现象 | 解决 |
---|---|
Jenkins 控制台提示 Permission denied (publickey) |
检查私钥是否匹配、凭据 ID 是否正确、sshagent 插件是否安装 |
第一次连接要求输入 yes/no |
已用 -o StrictHostKeyChecking=no |
部署后旧文件残留 | 可在解压前执行 rm -rf ${APP_NAME}/* |
5️⃣ 总结流程
- Jenkins 节点生成并注册 SSH Key
- 目标服务器加入公钥,实现免密
- Jenkinsfile:Build → Upload → Deploy
- 通过
sshagent
调用scp
&ssh
完成自动化部署
withcredentail vs sshagent
添加凭据
- 类型:
SSH Username with private key
- ID:
deploy-key
(示例 ID,后面 Pipeline 要用) - Username:目标服务器用户名
- Private Key:粘贴私钥内容或选择文件
- 类型:
2️⃣ Jenkinsfile 示例
1 | pipeline { |
关键点
withCredentials
credentialsId
:与 Jenkins 中创建的凭据 ID 对应。keyFileVariable
:在步骤内会生成一个临时文件,路径保存在$SSH_KEY
变量中。usernameVariable
:注入远程用户名。
-i $SSH_KEY
:显式指定刚注入的私钥文件。StrictHostKeyChecking=no
:避免首次连接交互。
3️⃣ 调试:结合 -vvv
如果需要排查连接问题,可以直接在 sh
命令里加 -vvv
:
1 | sh "ssh -vvv -i $SSH_KEY -o StrictHostKeyChecking=no $SSH_USER@${REMOTE_HOST} 'echo OK'" |
这样在 Jenkins 控制台日志里能看到完整握手与认证细节。
对比 sshagent
sshagent
会在整个 block 内自动加载密钥到ssh-agent
,不用-i
。withCredentials
则给你一个真实的密钥文件,更适合你需要scp
、rsync
等显式指定密钥的场景。两者都安全,关键看团队习惯:
- 频繁多处
ssh
→sshagent
方便。 - 只需一次
scp
/ssh
→withCredentials
足够。
- 频繁多处
总结:withCredentials([sshUserPrivateKey(...)])
让你在 Pipeline 里安全注入 SSH 私钥,并配合 scp/ssh -i $SSH_KEY
即可顺利上传 tar.gz 并远程部署,无需在 Jenkins 节点保存明文密钥文件。
QA 服务器忽略auth_keys
1 | ls -ld /home/user /home/user/.ssh |
1 | getenforce |
赏
使用支付宝打赏
使用微信打赏
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏